{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第十讲 if 语句"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "编程时经常需要检查一系列条件，并据此决定采取什么措施。在 Python 中，`if` 语句让你能够检查程序的当前状态，并采取相应的措施。\n",
    "\n",
    "在本讲中，你将学习条件测试，以检查你感兴趣的任何条件。你将学习简单的 `if` 语句，以及如何创建一系列复杂的 `if` 语句来确定当前到底处于什么条件下。接下来，你将把学到的知识应用于列表：编写一个 `for` 循环，以一种方式处理列表中的大多数元素，以另一种方式处理包含特定值的元素。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1 一个简单的示例"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面的示例演示了如何使用 `if` 语句来正确地处理特殊的情形。假设你有一个汽车列表，想将其中每辆汽车的名称打印出来。对于大多数汽车，应以首字母大写的方式打印其名称，但是汽车名 'bmw' 应以全大写的方式打印。下面的代码遍历这个列表，并以首字母大写的方式打印其中的汽车名，以全大写的方式打印 'bmw'："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Audi\n",
      "BMW\n",
      "Subaru\n",
      "Toyota\n"
     ]
    }
   ],
   "source": [
    "# cars.py\n",
    "\n",
    "cars = ['audi', 'bmw', 'subaru', 'toyota']\n",
    "\n",
    "for car in cars:\n",
    "    # ❶\n",
    "    if car == 'bmw':\n",
    "        print(car.upper())\n",
    "    else:\n",
    "        print(car.title())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个示例中的循环首先检查当前的汽车名是否是 'bmw'（见❶）。如果是，就以全大写的方式打印，否则以首字母大写的方式打印：\n",
    "\n",
    "```\n",
    "Audi\n",
    "BMW\n",
    "Subaru\n",
    "Toyota\n",
    "```\n",
    "\n",
    "这个示例涵盖了本讲将介绍的很多概念。下面先来介绍可用于在程序中检查条件的测试。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 条件测试"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "每条 `if` 语句的核心都是一个值为 `True` 或 `False` 的表达式，这种表达式被称为**条件测试**。Python 根据条件测试的值为 `True` 还是 `False` 来决定是否执行 `if` 语句中的代码。如果条件测试的值为 `True`，Python 就执行紧跟在 `if` 语句后面的代码；如果为 `False`，Python 就忽略这些代码。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1 检查是否相等"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "大多数条件测试将一个变量的当前值与特定的值进行比较。最简单的条件测试检查变量的值是否与特定的值相等："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "car = 'bmw'\n",
    "car == 'bmw'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "第一行使用一个等号将 `car` 的值设置为 `'bmw'`，这种做法你已经见过很多次了。接下来的一行使用两个等号 (`==`) 检查 `car` 的值是否为 `'bmw'`。这个相等运算符在它两边的值相等时返回 `True`，否则返回 `False`。在这个示例中，两边的值相等，因此 Python 返回 `True`。\n",
    "\n",
    "如果变量 `car` 的值不是 `'bmw'`，上述条件测试将返回 `False`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "car = 'audi'\n",
    "car == 'bmw'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一个等号是陈述，于是第一行代码可解读为：将变量 `car` 的值设置为 `'audi'`。两个等号则是发问，于是第二行代码可解读为：变量 `car` 的值是 `'bmw'` 吗？大多数编程语言使用等号的方式与这里的示例相同。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2 如何在检查是否相等时忽略大小写"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在 Python 中检查是否相等时是区分大小写的。例如，两个大小写不同的值被视为不相等：\n",
    "```python\n",
    "car = 'Audi'\n",
    "car == 'audi'\n",
    "False\n",
    "```\n",
    "如果大小写很重要，这种行为有其优点。但如果大小写无关紧要，只想检查变量的值，可将变量的值转换为全小写的，再进行比较："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "car = 'Audi'\n",
    "car.lower() == 'audi'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "无论值 `'Audi'` 的大小写如何，上述条件测试都将返回 `True`，因为它不区分大小写。`lower()` 方法不会修改存储在变量 `car` 中的值，因此这样的比较不会影响原来的变量："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Audi'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "car = 'Audi'\n",
    "car.lower() == 'audi'\n",
    "True\n",
    "car"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先，将首字母大写的字符串 `'Audi'` 赋给变量 `car`。然后，获取变量 `car` 的值并将其转换为全小写的，再将结果与字符串 `'audi'` 进行比较。这两个字符串相同，因此 Python 返回 `True`。如你所见，`lower()` 方法并没有影响存储在变量 `car` 中的值。\n",
    "\n",
    "网站采用类似的方式让用户输入的数据符合特定的格式。例如，网站可能使用类似的条件测试来确保用户名是独一无二的，而并非只是与另一个用户的大小写不同；在用户提交新的用户名时，把它转换为全小写的，并与所有既有用户名的全小写版本进行比较。执行这种检查，如果已经有用户名 `'john'`（不管大小写如何），则用户在提交 `'John'` 时将遭到拒绝。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 检查是否不相等"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "要判断两个值是否不等，可使用不等运算符 (`!=`)。下面使用一条 `if` 语句来演示如何使用不等运算符。我们将把顾客点的比萨配料 (topping) 存储在一个变量中，再打印一条消息，指出这名顾客点的配料是否是意式小银鱼 (anchovies)："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hold the anchovies!\n"
     ]
    }
   ],
   "source": [
    "# toppings.py\n",
    "\n",
    "requested_topping = 'mushrooms'\n",
    "\n",
    "if requested_topping != 'anchovies':\n",
    "    print(\"Hold the anchovies!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这些代码将 `requested_topping` 的值与 `'anchovies'` 进行比较。如果这两个值不等，Python 将返回 `True`，进而执行紧跟在 `if` 语句后面的代码；如果这两个值相等，Python 将返回 `False`，不执行紧跟在 `if` 语句后面的代码。\n",
    "\n",
    "由于 `requested_topping` 的值不是 `'anchovies'`，因此执行函数 `print()`：\n",
    "```\n",
    "Hold the anchovies!\n",
    "```\n",
    "你编写的大多数条件表达式会检查两个值是否相等，但有时候检查两个值是否不等的效率更高。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.4 数值比较"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "检查数值非常简单。例如，下面的代码检查一个人是否是 18 岁："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "age = 18\n",
    "age == 18"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "True\n",
    "```\n",
    "还可以检查两个数是否不等。例如，下面的代码在提供的答案不正确时打印一条消息："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "That is not the correct answer. Please try again!\n"
     ]
    }
   ],
   "source": [
    "# magic_number.py\n",
    "answer = 17\n",
    "\n",
    "if answer != 42:\n",
    "    print(\"That is not the correct answer. Please try again!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "答案 的值(17)不是神秘数42，条件得到满足，因此缩进的代码行得以执行：\n",
    "\n",
    "¹神秘数 (magic number) 出自科幻小说《银河系漫游指南》，指“生命、宇宙以及任何事情的终极答案”。——编者注\n",
    "```\n",
    "That is not the correct answer. Please try again!\n",
    "```\n",
    "条件语句可包含各种数学比较，如小于、小于等于、大于、大于等于："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "age = 19\n",
    "age < 21\n",
    "True\n",
    "age <= 21\n",
    "True\n",
    "age > 21\n",
    "False\n",
    "age >= 21\n",
    "False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "每种数学比较都能成为 `if` 语句的一部分，从而让你能够直接检查感兴趣的多个条件。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.5 检查多个条件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "你可能想同时检查多个条件。例如，有时候需要在两个条件都为 `True` 时才执行相应的操作，而有时候只要求一个条件为 `True`。在这些情况下，关键字 `and` 和 `or` 可助你一臂之力。\n",
    "\n",
    "#### 01. 使用 and 检查多个条件\n",
    "\n",
    "要检查两个条件是否都为 `True`，可使用关键字 `and` 将两个条件测试合而为一。如果每个条件测试都通过了，整个表达式就为 `True`；如果至少一个条件测试没有通过，整个表达式就为 `False`。\n",
    "\n",
    "例如，要检查两个人是否都不小于 21 岁，可使用下面的条件测试："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "age_0 = 22\n",
    "age_1 = 18\n",
    "age_0 >= 21 and age_1 >= 21"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "False\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "age_1 = 22\n",
    "age_0 >= 21 and age_1 >= 21"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "True\n",
    "```\n",
    "首先，定义两个用于存储年龄的变量：`age_0` 和 `age_1`。然后，检查这两个变量是否都大于或等于 21（见❶）。`and` 左边的条件测试通过了，但 `and` 右边的条件测试没有通过，因此整个条件表达式的结果为 `False`。接下来，将 `age_1` 改为 22（见❷），这样 `age_1` 的值也大于 21，因此两个条件测试都通过了，导致整个条件表达式的结果为 `True`。\n",
    "\n",
    "为了改善可读性，可将每个条件测试都分别放在一对括号内，但并非必须这样做。如果使用括号，条件测试将类似于下面这样：\n",
    "```python\n",
    "(age_0 >= 21) and (age_1 >= 21)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 02. 使用 or 检查多个条件\n",
    "\n",
    "关键字 `or` 也能够让你检查多个条件，但只要满足其中一个条件，就能通过整个条件测试。仅当所有条件测试都没有通过时，`or` 的表达式才为 `False`。\n",
    "\n",
    "下面再次检查两个人的年龄，但检查的是至少有一个人的年龄不小于 21 岁："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "age_0 = 22\n",
    "age_1 = 18\n",
    "# ❶\n",
    "age_0 >= 21 or age_1 >= 21"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "True\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "age_0 = 18\n",
    "# ❷\n",
    "age_0 >= 21 or age_1 >= 21"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同样，首先定义两个用于存储年龄的变量。由于 `age_0` 的条件测试通过了（见❶），因此整个表达式的结果为 `True`。接下来，将 `age_0` 减小为 18。在最后的条件测试中（见❷），两个条件测试都没有通过，因此整个表达式的结果为 `False`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.6 检查特定的值是否在列表中"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有时候，执行操作前必须检查列表中是否包含特定的值。例如，在结束用户的注册过程之前，需要检查他提供的用户名是否已在用户名列表中；在地图程序中，需要检查用户提交的位置是否已在已知位置的列表中。\n",
    "\n",
    "要判断特定的值是否在列表中，可使用关键字 `in`。下面看看你可能会为比萨店编写的一些代码。这些代码首先创建一个列表，其中包含用户点的比萨配料，然后检查特定的配料是否在该列表中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "requested_toppings = ['mushrooms', 'onions', 'pineapple']\n",
    "'mushrooms' in requested_toppings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "True\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'pepperoni' in requested_toppings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "False\n",
    "```\n",
    "关键字 `in` 让 Python 检查列表 `requested_toppings` 是否包含 `'mushrooms'` 和 `'pepperoni'`。这种技术很有用，让你能够在创建一个列表后，轻松地检查其中是否包含特定的值。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.7 检查特定的值是否不在列表中"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "还有些时候，确定特定的值不包含在列表中很重要。在这种情况下，可使用关键字 `not in`。例如，有一个列表包含被禁止在论坛上发表评论的用户，这样就可以在允许用户提交评论前检查他是否被禁言了："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# banned_users.py\n",
    "banned_users = ['andrew', 'carolina', 'david']\n",
    "user = 'marie'\n",
    "\n",
    "if user not in banned_users:\n",
    "    print(f\"{user.title()}, you can post a response if you wish.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里的 `if` 语句明白易懂：如果 `user` 的值不在列表 `banned_users` 中，Python 将返回 `True`，进而执行缩进的代码行。\n",
    "\n",
    "用户 `'marie'` 不在列表 `banned_users` 中，因此她将看到一条邀请她发表评论的消息：\n",
    "```\n",
    "Marie, you can post a response if you wish.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.8 布尔表达式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "随着对编程的了解越来越深入，你将遇到术语**布尔表达式**，它不过是条件测试的别名罢了。与条件表达式一样，布尔表达式的结果要么为 `True`，要么为 `False`。\n",
    "\n",
    "布尔值通常用于记录条件，如游戏是否正在运行或用户是否可以编辑网站的特定内容：\n",
    "```python\n",
    "game_active = True\n",
    "can_edit = False\n",
    "```\n",
    "在跟踪程序状态或程序中重要的条件方面，布尔值提供了一种高效的方式。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 动手试一试"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**练习 1：条件测试**\n",
    "\n",
    "编写一系列条件测试，将每个条件测试以及你对其结果的预测和实际结果都打印出来。你编写的代码应类似于下面这样：\n",
    "```python\n",
    "car = 'subaru'\n",
    "print(\"Is car == 'subaru'? I predict True.\")\n",
    "print(car == 'subaru')\n",
    "\n",
    "print(\"\\nIs car == 'audi'? I predict False.\")\n",
    "print(car == 'audi')\n",
    "```\n",
    "*   详细研究实际结果，直到你明白它为何为 `True` 或 `False`。\n",
    "*   创建至少 10 个条件测试，而且结果为 `True` 和 `False` 的条件测试分别至少有 5 个。\n",
    "\n",
    "--- \n",
    "**练习 2：更多条件测试**\n",
    "\n",
    "你并非只能创建 10 个条件测试。如果想尝试做更多的比较，可再编写一些条件测试，并将它们加入 `conditional_tests.py`。对于下面列出的各种情况，至少编写两个条件测试，结果分别为 `True` 和 `False`。\n",
    "\n",
    "*   检查两个字符串是否相等和不等。\n",
    "*   使用 `lower()` 方法的条件测试。\n",
    "*   涉及相等、不等、大于、小于、大于等于和小于等于的数值比较。\n",
    "*   使用关键字 `and` 和 `or` 的条件测试。\n",
    "*   测试特定的值是否在列表中。\n",
    "*   测试特定的值是否不在列表中。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 if 语句"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "理解条件测试之后，就可以开始编写 `if` 语句了。`if` 语句有很多种，选择使用哪一种取决于要测试的条件数。前面在讨论条件测试时，列举了多个 `if` 语句示例，下面更深入地讨论这个主题。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1 简单的 if 语句"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最简单的 `if` 语句只有一个条件测试和一个操作：\n",
    "```python\n",
    "if conditional_test:\n",
    "    do something\n",
    "```\n",
    "第一行可包含任意条件测试，而在紧跟在测试后面的缩进代码块中，可执行任意操作。如果条件测试的结果为 `True`，Python 就会执行紧跟在 `if` 语句后面的代码，否则 Python 将忽略这些代码。\n",
    "\n",
    "假设有一个表示某个人年龄的变量，而你想知道这个人是否到了投票的年龄，可使用如下代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# voting.py\n",
    "age = 19\n",
    "\n",
    "if age >= 18:\n",
    "    print(\"You are old enough to vote!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python 检查变量 `age` 的值是否大于或等于 18。答案是肯定的，因此 Python 执行缩进的函数 `print()`：\n",
    "```\n",
    "You are old enough to vote!\n",
    "```\n",
    "在 `if` 语句中，缩进的作用与 `for` 循环中相同。如果条件测试通过了，将执行 `if` 语句后面所有缩进的代码行，否则将忽略它们。\n",
    "\n",
    "可根据需要，在紧跟在 `if` 语句后面的代码块中添加任意数量的代码行。下面在一个人已到投票年龄时再打印一行输出，问他是否登记了："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "age = 19\n",
    "\n",
    "if age >= 18:\n",
    "    print(\"You are old enough to vote!\")\n",
    "    print(\"Have you registered to vote yet?\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "条件测试通过了，而且两个函数调用 `print()` 语句都缩进了，因此它们都将执行：\n",
    "```\n",
    "You are old enough to vote!\n",
    "Have you registered to vote yet?\n",
    "```\n",
    "如果 `age` 的值小于 18，这个程序将不会有任何输出。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 if-else 语句"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "经常需要在条件测试通过时执行一个操作，在没有通过时执行另一个操作。在这种情况下，可使用 Python 提供的 `if-else` 语句。`if-else` 语句块类似于简单的 `if` 语句，但其中的 `else` 语句让你能够指定条件测试未通过时要执行的操作。\n",
    "\n",
    "下面的代码在一个人已到投票年龄时显示与前面相同的消息，在不到投票年龄时显示一条新消息："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "age = 17\n",
    "\n",
    "if age >= 18:\n",
    "    # ●\n",
    "    print(\"You are old enough to vote!\")\n",
    "    print(\"Have you registered to vote yet?\")\n",
    "else:\n",
    "    # ●\n",
    "    print(\"Sorry, you are too young to vote.\")\n",
    "    print(\"Please register to vote as soon as you turn 18!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果●处的条件测试通过了，就执行第一组缩进的函数调用 `print()`。如果条件测试的结果为 `False`，就执行●处的 `else` 代码块。这次 `age` 小于 18，条件测试未通过，因此执行 `else` 代码块中的代码：\n",
    "```\n",
    "Sorry, you are too young to vote.\n",
    "Please register to vote as soon as you turn 18!\n",
    "```\n",
    "上述代码之所以可行，是因为只存在两种情形：要么已到投票年龄，要么不到。`if-else` 结构非常适用于让 Python 执行两种操作之一的情形。在这样简单的 `if-else` 结构中，总会执行两个操作中的一个。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3 if-elif-else 语句"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "你经常需要检查两个以上的情形，此时可使用 Python 提供的 `if-elif-else` 语句。Python 只执行 `if-elif-else` 结构中的一个代码块。它依次检查每个条件测试，直到遇到通过了的。条件测试通过后，Python 将执行紧跟在它后面的代码，并跳过余下的条件测试。\n",
    "\n",
    "在现实世界中，需要考虑的情形通常会超过两个。例如，来看一个根据年龄段收费的游乐场。\n",
    "*   4 岁以下免费。\n",
    "*   4 (含) ~18 岁收费 25 美元。\n",
    "*   年满 18 岁收费 40 美元。\n",
    "\n",
    "如果只使用一条 `if` 语句，该如何确定门票价格呢？下面的代码就能确定一个人所属的年龄段，并打印一条包含门票价格的消息："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Your admission cost is $2\n"
     ]
    }
   ],
   "source": [
    "# amusement_park.py\n",
    "\n",
    "age = 12\n",
    "# ❶\n",
    "if age < 4:\n",
    "    print(\"Your admission cost is $0.\")\n",
    "\n",
    "# ❷\n",
    "elif age < 18:\n",
    "    print(\"Your admission cost is $2\")\n",
    "\n",
    "# ❸\n",
    "else:\n",
    "    print(\"Your admission cost is $40.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "❶处的 `if` 测试检查一个人是否未满 4 岁。如果是，Python 就打印一条合适的消息，并跳过余下的测试。❷处的 `elif` 代码行其实是另一个 `if` 测试，它仅在前面的测试未通过时才会运行。在这里，我们知道这个人不小于 4 岁，因为第一个条件测试未通过。如果这个人未满 18 岁，Python 将打印相应的消息，并跳过 `else` 代码块。如果 `if` 测试和 `elif` 测试都未通过，Python 将运行❸处 `else` 代码块中的代码。\n",
    "\n",
    "在这个示例中，`if` 测试的结果为 `False`，因此不执行其代码块。`elif` 测试的结果为 `True` (12 小于 18)，因此执行其代码块。输出为一个句子，向用户指出门票价格：\n",
    "```\n",
    "Your admission cost is $2\n",
    "```\n",
    "只要年满 18 岁，前两个条件测试就都不能通过。在这种情况下，将执行 `else` 代码块，指出门票价格为 40 美元。\n",
    "\n",
    "为了让代码更简洁，可不在 `if-elif-else` 代码块中打印门票价格，而只是在其中设置门票价格，并在它后面添加一个函数调用 `print()`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "age = 12\n",
    "\n",
    "if age < 4:\n",
    "    price = 0\n",
    "elif age < 18:\n",
    "    price = 25\n",
    "else:\n",
    "    price = 40\n",
    "    \n",
    "print(f\"Your admission cost is ${price}.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "像上一个示例那样，缩进的代码行根据年龄设置变量 `price` 的值。在 `if-elif-else` 语句中设置 `price` 的值后，一个未缩进的函数调用 `print()` 会根据这个变量的值打印一条消息，指出门票价格。\n",
    "\n",
    "这些代码的输出与上一个示例相同，但 `if-elif-else` 语句所做的事更少：它只确定门票价格，而不是在确定门票价格的同时打印一条消息。除了效率更高以外，这些修订后的代码还更容易修改：要调整输出消息的内容，只需修改一个而不是三个函数调用 `print()`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.4 使用多个 elif 代码块"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "还可以根据需要使用任意数量的 `elif` 代码块。假设前述游乐场要给老年人打折，可再添加一个条件测试，判断顾客是否符合打折条件。下面假设年满 65 岁的老人可半价 (即 20 美元) 购买门票："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "age = 12\n",
    "\n",
    "if age < 4:\n",
    "    price = 0\n",
    "elif age < 18:\n",
    "    price = 25\n",
    "elif age < 65:\n",
    "    price = 40\n",
    "else:\n",
    "    price = 20\n",
    "    \n",
    "print(f\"Your admission cost is ${price}.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这些代码大都未变。第二个 `elif` 代码块通过检查年龄不小于 65 岁后，才将门票价格设置为全票价格——40 美元。请注意，在 `else` 代码块中，必须将所赋的值改为 20，因为仅当年龄达到 65 岁时，才会执行这个代码块。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.5 省略 else 代码块"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python 并不要求 `if-elif` 结构后面必须有 `else` 代码块。在一些情况下，`else` 代码块很有用；而在其他情况下，使用一条 `elif` 语句来处理特定的情形更清晰："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "age = 12\n",
    "\n",
    "if age < 4:\n",
    "    price = 0\n",
    "elif age < 18:\n",
    "    price = 25\n",
    "elif age < 65:\n",
    "    price = 40\n",
    "elif age >= 65:\n",
    "    price = 20\n",
    "\n",
    "print(f\"Your admission cost is ${price}.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后的 `elif` 代码块在顾客年龄满 65 岁时，将价格设置为 20 美元。这比使用 `else` 代码块更清晰一些。经过这样的修改，每个代码块都仅在通过了相应的条件测试时才会执行。\n",
    "\n",
    "`else` 是一条包罗万象的语句，只要不满足任何 `if` 或 `elif` 中的条件测试，其中的代码就会执行。这可能引入无效甚至恶意的数据。如果知道最终要测试的条件，应考虑使用一个 `elif` 代码块来代替 `else` 代码块。这样就可以肯定，仅当满足相应的条件时，代码才会执行。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.6 测试多个条件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`if-elif-else` 语句虽然功能强大，但仅适用于只有一个条件满足的情况：在遇到通过了的条件测试后，Python 就会跳过余下的条件测试。这种行为很好，效率很高，让你能够测试一个特定的条件。\n",
    "\n",
    "然而，有时候必须检查你关心的所有条件。在这种情况下，应使用一系列不包含 `elif` 和 `else` 代码块的简单 `if` 语句。在可能有多个条件为 `True`，且需要在每个条件为 `True` 时都采取相应措施时，适合使用这种方法。\n",
    "\n",
    "下面再来看看前面的比萨店示例。如果顾客点了两种配料，就需要确保在比萨中放入这些配料："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# toppings.py\n",
    "requested_toppings = ['mushrooms', 'extra cheese']\n",
    "\n",
    "if 'mushrooms' in requested_toppings:\n",
    "    print(\"Adding mushrooms.\")\n",
    "if 'pepperoni' in requested_toppings:\n",
    "    print(\"Adding pepperoni.\")\n",
    "if 'extra cheese' in requested_toppings:\n",
    "    print(\"Adding extra cheese.\")\n",
    "\n",
    "print(\"\\nFinished making your pizza!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先创建一个列表，其中包含顾客点的配料。第一条 `if` 语句检查顾客是否点了配料蘑菇 (`mushrooms`)。如果点了，就打印一条确认消息。❶处检查配料辣香肠 (`pepperoni`) 的代码也是一条简单的 `if` 语句，而不是 `elif` 或 `else` 语句。因此不管前一个条件测试是否通过，都将执行这个测试。最后一条 `if` 语句检查顾客是否要求多加芝士 (`extra cheese`)；不管前两个条件测试的结果如何，都会执行这些代码。每当这个程序运行时，都会执行这三个独立的条件测试。\n",
    "\n",
    "因为这个示例检查了每个条件，所以将在比萨中添加蘑菇并多加芝士：\n",
    "```\n",
    "Adding mushrooms.\n",
    "Adding extra cheese.\n",
    "\n",
    "Finished making your pizza!\n",
    "```\n",
    "如果像下面这样做，转而使用 `if-elif-else` 语句，代码将不能正确运行，因为只要有一个条件测试通过，就会跳过余下的条件测试："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "requested_toppings = ['mushrooms', 'extra cheese']\n",
    "\n",
    "if 'mushrooms' in requested_toppings:\n",
    "    print(\"Adding mushrooms.\")\n",
    "elif 'pepperoni' in requested_toppings:\n",
    "    print(\"Adding pepperoni.\")\n",
    "elif 'extra cheese' in requested_toppings:\n",
    "    print(\"Adding extra cheese.\")\n",
    "\n",
    "print(\"\\nFinished making your pizza!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "第一个条件测试检查列表中是否包含 `'mushrooms'`。它通过了，因此将在比萨中添加蘑菇。然而，Python 将跳过 `if-elif-else` 语句中余下的条件测试，不再检查列表中是否包含 `'extra cheese'` 和 `'pepperoni'`。结果就是，只会添加顾客点的第一种配料，不会添加其他配料：\n",
    "```\n",
    "Adding mushrooms.\n",
    "\n",
    "Finished making your pizza!\n",
    "```\n",
    "总之，如果只想运行一个代码块，就使用 `if-elif-else` 语句；如果要运行多个代码块，就使用一系列独立的 `if` 语句。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 动手试一试"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**练习 3：外星人颜色 1**\n",
    "假设在游戏中消灭了一个外星人，请创建一个名为 `alien_color` 的变量，并将其赋值为 `'green'`、`'yellow'` 或 `'red'`。\n",
    "*   编写一条 `if` 语句，测试外星人是否是绿色的。如果是，就打印一条消息，指出玩家获得了 5 分。\n",
    "*   编写这个程序的两个版本，上述条件测试在其中的一个版本中通过，在另一个版本中未通过 (未通过条件测试时没有输出)。\n",
    "\n",
    "---\n",
    "**练习 4：外星人颜色 2**\n",
    "像练习 3 那样设置外星人的颜色，并编写一个 `if-else` 结构。\n",
    "*   如果外星人是绿色的，就打印一条消息，指出玩家因消灭该外星人获得了 5 分。\n",
    "*   如果外星人不是绿色的，就打印一条消息，指出玩家获得了 10 分。\n",
    "*   编写这个程序的两个版本，在一个版本中将执行 `if` 代码块，在另一个版本中将执行 `else` 代码块。\n",
    "\n",
    "---\n",
    "**练习 5：外星人颜色 3**\n",
    "将练习 4 中的 `if-else` 结构改为 `if-elif-else` 结构。\n",
    "*   如果外星人是绿色的，就打印一条消息，指出玩家获得了 5 分。\n",
    "*   如果外星人是黄色的，就打印一条消息，指出玩家获得了 10 分。\n",
    "*   如果外星人是红色的，就打印一条消息，指出玩家获得了 15 分。\n",
    "*   编写这个程序的三个版本，分别在颜色为绿色、黄色和红色时打印相应的消息。\n",
    "\n",
    "---\n",
    "**练习 6：人生的不同阶段**\n",
    "设置变量 `age` 的值，再编写一个 `if-elif-else` 结构，根据 `age` 的值判断一个人处于人生的哪个阶段。\n",
    "*   如果年龄小于 2 岁，就打印一条消息，指出这个人是婴儿。\n",
    "*   如果年龄为 2 (含) ~4 岁，就打印一条消息，指出这个人是幼儿。\n",
    "*   如果年龄为 4 (含) ~13 岁，就打印一条消息，指出这个人是儿童。\n",
    "*   如果年龄为 13 (含) ~18 岁，就打印一条消息，指出这个人是少年。\n",
    "*   如果年龄为 18 (含) ~65 岁，就打印一条消息，指出这个人是中青年人。\n",
    "*   如果年龄达到 65 岁，就打印一条消息，指出这个人是老年人。\n",
    "\n",
    "---\n",
    "**练习 7：喜欢的水果**\n",
    "创建一个列表，其中包含你喜欢的水果，再编写一系列独立的 `if` 语句，检查列表中是否包含特定的水果。\n",
    "*   将该列表命名为 `favorite_fruits`，并让其包含三种水果。\n",
    "*   编写 5 条 `if` 语句，每条都检查某种水果是否在列表中。如果是，就打印一条像下面这样的消息：\n",
    "    `You really like bananas!`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4 使用 if 语句处理列表"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "结合使用 `if` 语句和列表，可完成一些有趣的任务：对列表中的特定值做特殊处理；高效管理不断变化的情形，如餐馆是否有特定的食材；证明代码在各种情形下都将按预期运行。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1 检查特殊元素"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本讲开头通过一个简单的示例演示了如何处理特殊值 'bmw'——需要采用不同的格式打印它。现在你对条件测试和 `if` 语句有了大致的认识，下面来进一步研究如何检查列表中的特殊值，并对其做合适的处理。\n",
    "\n",
    "继续使用前面的比萨店示例。这家比萨店在制作比萨时，每添加一种配料都打印一条消息。要以极高的效率编写这样的代码，可以创建一个包含顾客所点配料的列表，并使用一个循环来指出添加到比萨中的配料："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# toppings.py\n",
    "\n",
    "requested_toppings = ['mushrooms', 'green peppers', 'extra cheese']\n",
    "\n",
    "for requested_topping in requested_toppings:\n",
    "    print(f\"Adding {requested_topping}.\")\n",
    "    \n",
    "print(\"\\nFinished making your pizza!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输出很简单，因为上述代码不过是一个简单的 `for` 循环：\n",
    "```\n",
    "Adding mushrooms.\n",
    "Adding green peppers.\n",
    "Adding extra cheese.\n",
    "\n",
    "Finished making your pizza!\n",
    "```\n",
    "然而，如果比萨店的青椒 (`green peppers`) 用完了，该如何处理呢？为了妥善地处理这种情况，可在 `for` 循环中包含一条 `if` 语句："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "requested_toppings = ['mushrooms', 'green peppers', 'extra cheese']\n",
    "\n",
    "for requested_topping in requested_toppings:\n",
    "    if requested_topping == 'green peppers':\n",
    "        print(\"Sorry, we are out of green peppers right now.\")\n",
    "    else:\n",
    "        print(f\"Adding {requested_topping}.\")\n",
    "        \n",
    "print(\"\\nFinished making your pizza!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里在为比萨添加每种配料前都进行检查。`if` 语句检查顾客点的是否是青椒。如果是，就显示一条消息，指出不能点青椒的原因。`else` 代码块确保其他配料都将被添加到比萨中。\n",
    "\n",
    "输出表明，已经妥善地处理了顾客点的每种配料：\n",
    "```\n",
    "Adding mushrooms.\n",
    "Sorry, we are out of green peppers right now.\n",
    "Adding extra cheese.\n",
    "\n",
    "Finished making your pizza!\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2 确定列表不为空"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "到目前为止，我们对于要处理的每个列表都做了一个简单的假设——它们都至少包含一个元素。因为马上就要让用户来提供存储在列表中的信息，所以不能再假设每次循环时列表非空。有鉴于此，在运行 `for` 循环前确定列表非空很重要。\n",
    "\n",
    "下面在制作比萨前检查顾客点的配料列表是否为空。如果列表为空，就向顾客确认是否要点原味比萨 (plain pizza)；如果列表非空，就像前面的示例那样制作比萨："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "ename": "IndentationError",
     "evalue": "expected an indented block after 'for' statement on line 4 (1775015802.py, line 6)",
     "output_type": "error",
     "traceback": [
      "  \u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[19]\u001b[39m\u001b[32m, line 6\u001b[39m\n\u001b[31m    \u001b[39m\u001b[31melse:\u001b[39m\n         ^\n\u001b[31mIndentationError\u001b[39m\u001b[31m:\u001b[39m expected an indented block after 'for' statement on line 4\n"
     ]
    }
   ],
   "source": [
    "requested_toppings = []\n",
    "\n",
    "if requested_toppings:\n",
    "    for requested_topping in requested_toppings:\n",
    "        # ...\n",
    "else:\n",
    "    # ..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里在 `if` 语句中将列表名用作条件时，Python 将在列表至少包含一个元素时返回 `True`，并在列表为空时返回 `False`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3 使用多个列表"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先定义一个列表，其中包含比萨店供应的配料。请注意，如果比萨店供应的配料是固定的，也可以使用一个元组来存储它们。然后创建一个列表，其中包含顾客点的配料。请注意那个不同寻常的配料 `'french fries'`（见❶）。接下来，遍历顾客点的每种配料，都检查它是否在供应的配料列表中（见❷）。如果答案是肯定的，就将其加入比萨，否则则运行 `else` 代码块（见❸）：打印一条消息，告诉顾客不供应这种配料。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Adding mushrooms.\n",
      "Sorry, we don't have french fries.\n",
      "Adding extra cheese.\n",
      "\n",
      "Finished making your pizza!\n"
     ]
    }
   ],
   "source": [
    "available_toppings = ['mushrooms', 'olives', 'green peppers', \n",
    "                        'pepperoni', 'pineapple', 'extra cheese']\n",
    "# ❶\n",
    "requested_toppings = ['mushrooms', 'french fries', 'extra cheese']\n",
    "\n",
    "for requested_topping in requested_toppings:\n",
    "    # ❷\n",
    "    if requested_topping in available_toppings:\n",
    "        print(f\"Adding {requested_topping}.\")\n",
    "    # ❸\n",
    "    else:\n",
    "        print(f\"Sorry, we don't have {requested_topping}.\")\n",
    "        \n",
    "print(\"\\nFinished making your pizza!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这些代码的输出整洁而且包含足够的信息：\n",
    "```\n",
    "Adding mushrooms.\n",
    "Sorry, we don't have french fries.\n",
    "Adding extra cheese.\n",
    "\n",
    "Finished making your pizza!\n",
    "```\n",
    "通过寥寥几行代码，我们就高效地处理了一种真实的情形！"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 动手试一试"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**练习 8：以特殊方式跟管理员打招呼**\n",
    "创建一个至少包含 5 个用户名的列表，并将其中的一个用户命名为 `'admin'`。想象你要编写代码，在每个用户登录网站后都打印一条问候消息。遍历用户名列表，向每个用户打印一条问候消息。\n",
    "*   如果用户名为 `'admin'`，就打印一条特殊的问候消息，如下所示：\n",
    "    `Hello admin, would you like to see a status report?`\n",
    "*   否则，打印一条普通的问候消息，如下所示：\n",
    "    `Hello Jaden, thank you for logging in again.`\n",
    "\n",
    "---\n",
    "**练习 9：处理没有用户的情形**\n",
    "在为练习 8 编写的程序中，添加一条 `if` 语句，检查用户名列表是否为空。\n",
    "*   如果为空，就打印如下消息：\n",
    "    `We need to find some users!`\n",
    "*   删除列表中的所有用户名，确认将打印正确的消息。\n",
    "\n",
    "---\n",
    "**练习 10：检查用户名**\n",
    "按照下面的说明编写一个程序，模拟网站如何确保每个用户的用户名都独一无二。\n",
    "*   创建一个至少包含 5 个用户名的列表，并将其命名为 `current_users`。\n",
    "*   再创建一个包含 5 个用户名的列表，将其命名为 `new_users`，并确保其中有一两个用户名也在 `current_users` 中。\n",
    "*   遍历列表 `new_users`，检查其中的每个用户名是否已被使用。如果是，就打印一条消息，指出需要输入别的用户名；否则，打印一条消息，指出这个用户名未被使用。\n",
    "*   确保比较时不区分大小写。换句话说，如果用户名 `'John'` 已被使用，应拒绝用户名 `'JOHN'`。(为此，需要创建列表 `current_users` 的副本，其中包含当前所有用户名的全小写版本。)\n",
    "\n",
    "---\n",
    "**练习 11：序数**\n",
    "序数表示顺序位置，如 1st 和 2nd。序数大多以 th 结尾，只有 1st、2nd、3rd 例外。\n",
    "*   在一个列表中存储数 1~9。\n",
    "*   遍历这个列表。\n",
    "*   在循环中使用一个 `if-elif-else` 结构，打印每个数对应的序数。输出内容应为 \"1st 2nd 3rd 4th 5th 6th 7th 8th 9th\"，每个序数都独占一行。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5 设置 if 语句的格式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本讲的每个示例都展示了 `if` 语句的格式设置习惯。在条件测试的格式设置方面，PEP 8 提供的唯一建议是：在诸如 `==`、`>=` 和 `<=` 等比较运算符两边各添加一个空格。例如：\n",
    "```python\n",
    "if age < 4:\n",
    "```\n",
    "要比\n",
    "```python\n",
    "if age<4:\n",
    "```\n",
    "更好。\n",
    "\n",
    "这样的空格不会影响 Python 对代码的解读，只是让代码阅读起来更容易。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 动手试一试"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**练习 12：设置 if 语句的格式**\n",
    "审核你在本讲编写的程序，确保正确地设置了条件测试的格式。\n",
    "\n",
    "---\n",
    "**练习 13：自己的想法**\n",
    "与刚拿起本书时相比，现在你是一名能力更强的程序员了。鉴于你对如何......(后续文字缺失)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6 小结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在本讲中，你首先学习了如何编写结果要么为 `True`、要么为 `False` 的条件测试。然后学习了如何编写简单的 `if` 语句、`if-else` 语句和 `if-elif-else` 语句。在程序中，可以使用这些结构来测试特定的条件，以确定这些条件是否满足。你接着学习了在使用 `for` 循环高效处理列表元素时，如何对某些元素做特殊处理。你还再次学习了 Python 在代码格式方面提出的建议。遵循这些建议，即便你编写的程序越来越复杂，其代码也依然易于阅读和理解。\n",
    "\n",
    "在下一讲中，你将学习 Python 字典。字典类似于列表，但能够让你将不同的信息关联起来。你还将学习如何创建和遍历字典，以及如何将字典与列表和 `if` 语句结合起来使用。学习字典让你能够模拟现实世界中的更多情形。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
